<?php
class Simplium_Db_Adapter_Abstract implements Simplium_Db_Adapter_Interface{
	protected $_connection = null;
	protected $_options = array();
	
	
	protected $_autoQuoteIdentifiers = true;
	
	protected $_dataTypes = array(
		Simplium_Db::BIGINT_TYPE => Simplium_Db::BIGINT_TYPE, 
		Simplium_Db::INT_TYPE => Simplium_Db::INT_TYPE, 
		Simplium_Db::FLOAT_TYPE => Simplium_Db::FLOAT_TYPE);
	
	/**
	 * @param array $array
	 */
	public function connect(array $array = array()){}

	/**
	 * @param string $tblname
	 * @param array $data
	 */
	public function insert($tblname, array $data){}
	
	/**
	 * Quotes a value for an SQL statement.
	 *
	 * @param mixed $value
	 * @param mixed $type
	 * @return mixed An SQL-safe quoted value (or string of separated values).
	 */
	public function quote($value, $type = null){
		
		if(is_array($value)){
			foreach($value as &$val){
				$val = $this->quote($val, $type);
			}
			return implode(', ', $value);
		}
		
		if($type !== null && array_key_exists($type = strtoupper($type), $this->_dataTypes)){
			$quotedValue = '0';
			switch($this->_dataTypes[$type]){
				case Simplium_Db::INT_TYPE: // 32-bit integer
					$quotedValue = (string) intval($value);
					break;
				case Simplium_Db::BIGINT_TYPE: // 64-bit integer
					if(preg_match('/^(
						[+-]?                  # optional sign
							(?:
								0[Xx][\da-fA-F]+     # ODBC-style hexadecimal
								|\d+                 # decimal or octal, or MySQL ZEROFILL decimal
								(?:[eE][+-]?\d+)?    # optional exponent on decimals or octals
							)
						)/x', (string) $value, $matches)){
						$quotedValue = $matches[1];
					}
					break;
				case Simplium_Db::FLOAT_TYPE: // float or decimal
					$quotedValue = sprintf('%F', $value);
			}
			return $quotedValue;
		}

		return $this->_quote($value);
	}
	
	/**
	 * Quotes a value and places into a piece of text at a placeholder.
	 *
	 * @param string $text
	 * @param mixed $value
	 * @param string $type
	 * @param integer $count
	 * @return string An SQL-safe quoted value placed into the original text.
	 */
	public function quoteInto($text, $value, $type = null, $count = null){
		if($count === null){
			return str_replace('?', $this->quote($value, $type), $text);
		}else{
			while($count > 0){
				if(strpos($text, '?') !== false){
					$text = substr_replace($text, $this->quote($value, $type), strpos($text, '?'), 1);
				}
				--$count;
			}
			return $text;
		}
	}
	
	public function quoteIdentifier($ident, $auto = false){
		return $this->_quoteIdentifier($ident, $auto);
	}
	
	/**
	 * Quote a raw string.
	 *
	 * @param string $value
	 * @return string Quoted string
	 */
	protected function _quote($value){
		if(is_int($value)){
			return $value;
		}elseif(is_float($value)){
			return sprintf('%F', $value);
		}
		return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
	}
	
	/**
	 * Quote an identifier.
	 *
	 * @param string $value
	 * @param boolean $auto
	 * @return string
	 */
	protected function _quoteIdentifier($value, $auto = false){
		if($auto === false || $this->_autoQuoteIdentifiers === true){
			$q = $this->getQuoteIdentifierSymbol();
			return ($q . str_replace("$q", "$q$q", $value) . $q);
		}
		return $value;
	}
	
	/**
	 * Returns the symbol the adapter uses for delimited identifiers.
	 *
	 * @return string
	 */
	public function getQuoteIdentifierSymbol(){
		return '"';
	}
	
	/**
	 * 
	 * @param array $options
	 * @return Simplium_Db_Adapter_Abstract
	 */
	public function setOptions(array $options = array()){
		$this->_options = $options;
		
		return $this;
	}
	
	/**
	 * Convert an array or string
	 * into a string to put in a WHERE clause.
	 *
	 * @param mixed $where
	 * @return string
	 */
	protected function _whereExpr($where){
		if(empty($where)){
			return $where;
		}
		
		if(! is_array($where)){
			$where = array($where);
		}
		
		foreach($where as $cond => &$term){
			// is $cond an int? (i.e. Not a condition)
			if(is_int($cond)){
				// Do nothing
			}else{
				$term = $this->quoteInto($cond, $term);
			}
			$term = '(' . $term . ')';
		}
		
		$where = implode(' AND ', $where);
		return $where;
	}

	/**
	 * @param string $tblname
	 * @param array $data
	 * @param mixed $where
	 */
	public function update($tblname, array $data, $where = ''){}

	/**
	 * @param string $tblname
	 * @param mixed $where
	 */
	public function delete($tblname, $where = ''){}
}